package com.yc.security.authorize;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.yc.security.utils.JwtTokenUtil;
import io.jsonwebtoken.SignatureException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import io.jsonwebtoken.ExpiredJwtException;

/**
 * 请求过滤器对jwt token令牌进行拦截  进行用户认证 以及权限的校验
 * @title
 * @author kukaha
 * @updateTime  19:24
 * @throws
 * @return
 */
//@Component
public class JwtRequestFilter extends OncePerRequestFilter {

	/**
	 * 令牌头
	 */
	private static final String BEARER = "Bearer ";

	/**
	 * 令牌key
	 */
	@Value("${jwt.header}")
	private String tokenHeader;

	/**
	 * 注入对用户认证的逻辑服务
	 * @title
	 * @author kukaha
	 * @updateTime  19:26
	 */
	@Autowired
	private UserDetailsService jwtUserDetailsServiceImpl;

	@Autowired
	private JwtTokenUtil jwtTokenUtil;
	

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws ServletException, IOException {
		final String requestTokenHeader = request.getHeader(tokenHeader);
		String username = null;
		String jwtToken = null;
		/**
		 * JWT报文表头的格式是"Bearer token". 去除"Bearer ",直接获取token
		 */
		if (requestTokenHeader != null && requestTokenHeader.startsWith(BEARER)) {
			jwtToken = requestTokenHeader.substring(7);
//			try {
				username = jwtTokenUtil.getUsernameFromToken(jwtToken);
//			} catch (IllegalArgumentException e) {
//				logger.error("jwtToken非法令牌,解析失败");
//			} catch (ExpiredJwtException e) {
//				logger.error("jwtToken令牌过期");
//			} catch (SignatureException e){
//				logger.error("jwtToken签名与本地计算的签名不匹配");
//			}
		} else {
			logger.warn("jwtToken没有以Bearer 开头 已经过滤的路径");
		}
		/**
		 * 验证令牌的合法性
		 */
		if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
			UserDetails userDetails = this.jwtUserDetailsServiceImpl.loadUserByUsername(username);
			/**
			 * 如果令牌有效则将他手动设置到SecurityContextHolder中,以便从上下文中获取用户信息
			 */
			if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
				UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
						userDetails, null, userDetails.getAuthorities());
				usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
				SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
			}
		}
		chain.doFilter(request, response);
	}
}
